'\" te
.\"  Copyright (c) 2004, Sun Microsystems, Inc.  All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
.TH PM_POWER_HAS_CHANGED 9F "Jul 22, 2004"
.SH NAME
pm_power_has_changed \- Notify Power Management framework of autonomous power
level change
.SH SYNOPSIS
.nf
#include <sys/ddi.h>
#include <sys/sunddi.h>

\fBint\fR \fBpm_power_has_changed\fR(\fBdev_info_t *\fR\fIdip,\fR int \fIcomponent\fR, int \fIlevel\fR);
.fi

.SH INTERFACE LEVEL
illumos DDI specific (illumos DDI)
.SH PARAMETERS
.ne 2
.na
\fB\fIdip\fR\fR
.ad
.RS 7n
Pointer to the device \fBdev_info\fR structure
.RE

.sp
.ne 2
.na
\fB\fIcomponent\fR\fR
.ad
.RS 13n
Number of the component that has changed power level
.RE

.sp
.ne 2
.na
\fB\fIlevel\fR\fR
.ad
.RS 9n
Power level to which the indicated component has changed
.RE

.SH DESCRIPTION
The \fBpm_power_has_changed\fR(9F) function notifies the Power Management
framework that the power level of component of \fIdip \fR has changed to
\fIlevel\fR.
.sp
.LP
Normally power level changes are initiated by the Power Management framework
due to device idleness, or through a request to the framework from the driver
via \fBpm_raise_power\fR(9F) or \fBpm_lower_power\fR(9F), but some devices may
change power levels on their own. For the framework to track the power level of
the device under these circumstances, the framework must be notified of
autonomous power level changes by a call to \fBpm_power_has_changed()\fR.
.sp
.LP
Because of the asynchronous nature of these events, the Power Management
framework might have called \fBpower\fR(9E) between the device's autonomous
power level change and the driver calling \fBpm_power_has_changed()\fR, or the
framework may be in the process of changing the power level when
\fBpm_power_has_changed()\fR is called. To handle these situations correctly,
the driver should verify that the device is indeed at the level or set the
device to the level if it doesn't support inquirying of power levels, before
calling \fBpm_power_has_changed()\fR. In addition, the driver should prevent a
\fBpower\fR(9E) entry point from running in parallel with
\fBpm_power_has_changed()\fR.
.LP
Note -
.sp
.RS 2
If this function is called as a result of entry into the driver's
\fBattach\fR(9E), \fBdetach\fR(9E) or \fBpower\fR(9E) entry point, this
function must be called from the same thread which entered \fBattach\fR(9E),
\fBdetach\fR(9E) or \fBpower\fR(9E).
.RE
.SH RETURN VALUES
The \fBpm_power_has_changed()\fR function returns:
.sp
.ne 2
.na
\fB\fBDDI_SUCCESS\fR\fR
.ad
.RS 15n
The power level of component was successfully updated to \fIlevel\fR.
.RE

.sp
.ne 2
.na
\fB\fBDDI_FAILURE\fR\fR
.ad
.RS 15n
Invalid component \fIcomponent\fR or power level \fIlevel\fR.
.RE

.SH CONTEXT
This function can be called from user or kernel context. This function can also
be called from interrupt context, providing that it is not the first Power
Management function called by the driver.
.SH EXAMPLES
A hypothetical driver might include this code to handle
\fBpm_power_has_changed\fR(9F):
.sp
.in +2
.nf
static int
xxusb_intr(struct buf *bp)
{

	...


	/*
	 * At this point the device has informed us that it has
	 * changed power level on its own. Inform this to framework.
	 * We need to take care of the case when framework has
	 * already called power() entry point and changed power level
	 * before we were able to inform framework of this change.
         * Handle this by comparing the informed power level with
	 * the actual power level and only doing the call if they
	 * are same. In addition, make sure that power() doesn't get
	 * run in parallel with this code by holding the mutex.
	 */
        ASSERT(mutex_owned(&xsp->lock));
	if (level_informed == *(xsp->level_reg_addr)) {
		if (pm_power_has_changed(xsp->dip, XXUSB_COMPONENT,
		    level_informed) != DDI_SUCCESS) {
			mutex_exit( &xsp->lock);
			return(DDI_INTR_UNCLAIMED);
		}
        }

	....

}


xxdisk_power(dev_info *dip, int comp, int level)
{
	mutex_enter( xsp->lock);

	...

	...

}
.fi
.in -2

.SH ATTRIBUTES
See \fBattributes\fR(7) for a description of the following attributes:
.sp

.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE	ATTRIBUTE VALUE
_
Interface Stability	Committed
.TE

.SH SEE ALSO
.BR pm (4D),
.BR power.conf (5),
.BR attach (9E),
.BR detach (9E),
.BR power (9E),
.BR pm_busy_component (9F),
.BR pm_idle_component (9F),
.BR pm_lower_power (9F),
.BR pm_raise_power (9F),
.BR pm (9P),
.BR pm-components (9P)
.sp
.LP
\fIWriting Device Drivers\fR
